package cn.snowheart.factory;

import cn.snowheart.factory.abstractfactory.AMDComponentFactory;
import cn.snowheart.factory.abstractfactory.ComponentAbstractFactory;
import cn.snowheart.factory.abstractfactory.IntelComponentFactory;
import cn.snowheart.factory.component.Component;
import cn.snowheart.factory.enums.ComponentType;
import cn.snowheart.factory.enums.FactoryType;
import cn.snowheart.factory.factorymethod.AMDFactory;
import cn.snowheart.factory.factorymethod.ComponentMethodFactory;
import cn.snowheart.factory.simplefactory.SimpleComponentFactory;

/**
 * @author liuwanxiang
 * @version 2019/7/1
 */
public class ComputerTests {

    public static void main(String[] args) {
        simpleFactoryTest();

        factoryMethodTest();

        abstractFactoryTest();
    }

    /**
     * 简单工厂模式（非23种设计模式之一）
     * 静态工厂模式 = 简单工厂模式的方法签名改为static
     * 特点：
     * - 只有一个Core工厂，来负责整个对象体系的创建
     * 优势：
     * - 将new对象的逻辑与使用对象的逻辑分开，解决变与不变分离的扩展性问题
     * 缺点：
     * - 只是将if-else逻辑移动了位置，如果有一个参数还好；多个参数的话，工厂方法内部将会出现if-else灾难。
     */
    private static void simpleFactoryTest() {
        SimpleComponentFactory factory = new SimpleComponentFactory();
        Component component = factory.createComponent(ComponentType.CPU, FactoryType.AMD);
        System.out.println(component.getName());

        component = factory.createComponent(ComponentType.GPU, FactoryType.INTEL);
        System.out.println(component.getName());
    }

    /**
     * 工厂方法模式
     * 特点：
     * - 工厂类也做成抽象接口，对产品分类，Intel和AMD不同的工厂，生产不同的产品类
     * 优势：
     * - 解决了不同厂商的if-else逻辑
     * 缺点：
     * - 并没有彻底的解决工厂方法中的if-else逻辑
     */
    private static void factoryMethodTest() {
        ComponentMethodFactory factory = new AMDFactory();
        Component component = factory.createComponent(ComponentType.CPU);
        System.out.println(component.getName());

        component = factory.createComponent(ComponentType.GPU);
        System.out.println(component.getName());
    }

    /**
     * 抽象工厂模式
     * 特点：
     * - 工厂方法中if-else逻辑，拆分成多个方法实现。
     * 优势：
     * - 进一步解决同一厂商内部不同产品间的if-else逻辑
     * 缺点：
     * - 使用工厂的地方，可能需要通过if-else逻辑来确定具体的工厂类
     */
    private static void abstractFactoryTest() {
        ComponentAbstractFactory factory = new AMDComponentFactory();
        Component component = factory.createCPU();
        System.out.println(component.getName());

        factory = new IntelComponentFactory();
        component = factory.createGPU();
        System.out.println(component.getName());
    }

}
